﻿using CacheHelper;
using Enyim.Caching;
using Enyim.Caching.Memcached;
using System;
using System.Collections.Generic;

namespace InstanceMemcache
{

    public class Memcached : ICache
    {
        private static MemcachedClient CacheClient ;

        static readonly object _lock = new object();
        static Memcached()
        {
            if (CacheClient == null)
            {
                lock (_lock)
                {
                    if (CacheClient == null)
                    {
                        CacheClient = new MemcachedClient();
                    }
                 }

            }
        }
        /// <summary>
        /// 获取缓存
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="cacheKey"></param>
        /// <returns></returns>
        public T GetCache<T>(string cacheKey) where T : class
        {
            try
            {
                return (T)CacheClient.Get(cacheKey);
            }
            catch
            {
                return default(T);
            }
        }

        /// <summary>
        /// 写入缓存
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value"></param>
        /// <param name="cacheKey"></param>
        public void WriteCache<T>(T value, string cacheKey) where T : class
        {
            bool result = CacheClient.Store(StoreMode.Set, cacheKey, value);
            if (!result)
            {
                CacheClient = new MemcachedClient();
                CacheClient.Store(StoreMode.Set, cacheKey, value);
            }

        }

       
        /// <summary>
        /// 写入缓存，绝对过期时间
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value"></param>
        /// <param name="cacheKey"></param>
        public void WriteCache<T>(T value, string cacheKey, DateTime dateTime) where T : class
        {
            //CacheClient.Store(StoreMode.Set, cacheKey, value);

            bool result = CacheClient.Store(Exists(cacheKey) ? StoreMode.Set : StoreMode.Replace, cacheKey, value, dateTime);
            if (!result)
            {
                CacheClient = new MemcachedClient();
                CacheClient.Store(Exists(cacheKey) ? StoreMode.Set : StoreMode.Replace, cacheKey, value, dateTime);
            }

        }


        /// <summary>
        /// 写入缓存，相对过期时间
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value"></param>
        /// <param name="cacheKey"></param>
        /// <param name="expireTime"></param>
        public void WriteCache<T>(T value, string cacheKey, TimeSpan validFor) where T : class
        {
            //CacheClient.Store(StoreMode.Set, cacheKey, value, expireTime);

            bool result = CacheClient.Store(Exists(cacheKey) ? StoreMode.Set : StoreMode.Replace, cacheKey, value, validFor);
            if (!result)
            {
                CacheClient = new MemcachedClient();
                CacheClient.Store(StoreMode.Set, cacheKey, value);
            }
        }


        /// <summary>
        /// 移除缓存
        /// </summary>
        /// <param name="cacheKey"></param>
        public void RemoveCache(string cacheKey)
        {
            CacheClient.Remove(cacheKey);
        }

        /// <summary>
        /// 移除所有缓存
        /// </summary>
        public void RemoveCache()
        {
            CacheClient.FlushAll();
        }

        /// <summary>
        /// 是否存在
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public bool Exists(string key)
        {
            return CacheClient.Get(key) != null;
        }

        /// <summary>
        ///  缓存数量
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public long CacheCount()
        {
            return 0;
        }

        /// <summary>
        ///  物理内存使用
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public long CacheMemony()
        {
            return 0;
        }
    }
}
